package com.hsjk.szwj.module.chuangkit.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.hsjk.szwj.framework.common.pojo.PageResult;
import com.hsjk.szwj.framework.security.core.util.SecurityFrameworkUtils;
import com.hsjk.szwj.module.chuangkit.controller.admin.vo.CopyDesignReqVO;
import com.hsjk.szwj.module.chuangkit.controller.admin.vo.CopyDesignRespVO;
import com.hsjk.szwj.module.chuangkit.controller.admin.vo.DeleteDesignReqVO;
import com.hsjk.szwj.module.chuangkit.controller.admin.vo.GetUserDesignsReqVO;
import com.hsjk.szwj.module.chuangkit.controller.admin.vo.GetUserDesignsRespVO;
import com.hsjk.szwj.module.chuangkit.controller.admin.vo.TemplateCancelCollectionReqVO;
import com.hsjk.szwj.module.chuangkit.controller.admin.vo.TemplateCollectionListReqVO;
import com.hsjk.szwj.module.chuangkit.controller.admin.vo.TemplateCollectionListRespVO;
import com.hsjk.szwj.module.chuangkit.controller.admin.vo.TemplateCollectionReqVO;
import com.hsjk.szwj.module.chuangkit.controller.admin.vo.TemplateForApiUserReqVO;
import com.hsjk.szwj.module.chuangkit.controller.admin.vo.TemplateForApiUserRespVO;
import com.hsjk.szwj.module.chuangkit.controller.admin.vo.TokenRespVO;
import com.hsjk.szwj.module.chuangkit.controller.admin.vo.UpdateTitleReqVO;
import com.hsjk.szwj.module.chuangkit.service.IChuangKitService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author chenjiawei
 * @desc
 * @Date 2023/09/26 22:09
 **/
@Service
@Slf4j
public class ChuangKitServiceImpl implements IChuangKitService {
    @Value("${szwj.chuangkit.open-platform-base-url}")
    private String openPlatformBaseUrl;

    @Value("${szwj.chuangkit.template-base-url}")
    private String templateBaseUrl;

    @Value("${szwj.chuangkit.template-collection-url}")
    private String templateCollectionBaseUrl;

    @Value("${szwj.chuangkit.app-id}")
    private String appId;

    @Value("${szwj.chuangkit.app-secret}")
    private String appSecret;

    @Value("${szwj.chuangkit.package-id}")
    private String packageId;

    private final static Integer SUCCESS_CODE = 200;

    @Override
    public TokenRespVO getApiToken() {
        String url = openPlatformBaseUrl + "/getApiToken.do";
        Long timestamp = System.currentTimeMillis() - 50000;
        Map<String, Object> params = new HashMap<>(3);
        params.put("api_id", appId);
        params.put("timestamp", timestamp);
        params.put("sign", getSign(timestamp));
        String post = HttpUtil.post(url, params);
        JSONObject bodyObject = JSONUtil.parseObj(post);
        JSONObject bodyVal = (JSONObject) bodyObject.get("body");
        Integer code = bodyVal.getInt("code");
        TokenRespVO respVO = new TokenRespVO();
        if (SUCCESS_CODE.equals(code)) {
            JSONObject dataObj = (JSONObject) bodyVal.getObj("data");
            String accessToken = dataObj.getStr("accessToken");
            Long tokenExpireTime = dataObj.getLong("tokenExpireTime");
            String refreshToken = dataObj.getStr("refreshToken");
            Long refreshTokenExpireTime = dataObj.getLong("refreshTokenExpireTime");
            respVO.setAccessToken(accessToken);
            respVO.setRefreshToken(refreshToken);
            respVO.setTokenExpireTime(tokenExpireTime);
            respVO.setRefreshTokenExpireTime(refreshTokenExpireTime);
        }
        return respVO;
    }

    @Override
    public TokenRespVO refreshToken(String refreshToken) {
        String url = openPlatformBaseUrl + "/refreshApiToken.do";
        Map<String, Object> params = new HashMap<>(3);
        params.put("appId", appId);
        params.put("refreshToken", refreshToken);
        String post = HttpUtil.post(url, params);
        JSONObject bodyObject = JSONUtil.parseObj(post);
        JSONObject bodyVal = (JSONObject) bodyObject.get("body");
        Integer code = bodyVal.getInt("code");
        TokenRespVO respVO = new TokenRespVO();
        if (SUCCESS_CODE.equals(code)) {
            JSONObject dataObj = (JSONObject) bodyVal.getObj("data");
            String accessToken = dataObj.getStr("accessToken");
            Long tokenExpireTime = dataObj.getLong("tokenExpireTime");
            String newRefreshToken = dataObj.getStr("refreshToken");
            Long refreshTokenExpireTime = dataObj.getLong("refreshTokenExpireTime");
            respVO.setAccessToken(accessToken);
            respVO.setRefreshToken(newRefreshToken);
            respVO.setTokenExpireTime(tokenExpireTime);
            respVO.setRefreshTokenExpireTime(refreshTokenExpireTime);
        }
        return respVO;
    }

    @Override
    public String getSign(Long timestamp) {
        String val = "appId&" + appId + "timestamp&" + timestamp + "#" + appSecret;
        return DigestUtil.md5Hex(val).toUpperCase();
    }

    @Override
    public PageResult<GetUserDesignsRespVO> getUserDesigns(GetUserDesignsReqVO reqVO) {
        String url = openPlatformBaseUrl + "/queryUserDesigns.do";
        Map<String, Object> params = new HashMap<>(9);
        params.put("app_id", appId);
        params.put("user_flag", reqVO.getUserFlag());
        params.put("token", reqVO.getToken());
        params.put("kind_id", reqVO.getKindId());
        params.put("time_order", reqVO.getTimeOrder());
        params.put("page_no", reqVO.getPageNo());
        params.put("page_size", reqVO.getPageSize());
        if (ObjectUtil.isNotNull(reqVO.getTerminal())) {
            params.put("terminal", reqVO.getTerminal());
        }
        if (ObjectUtil.isNotNull(reqVO.getDesignName())) {
            params.put("design_name", reqVO.getDesignName());
        }
        String post = HttpUtil.post(url, params);
        JSONObject bodyObject = JSONUtil.parseObj(post);
        JSONObject bodyVal = (JSONObject) bodyObject.get("body");
        log.info("返回值：{}", bodyVal.toString());
        Integer code = bodyVal.getInt("code");
        List<GetUserDesignsRespVO> list = new ArrayList<>();
        Long count = 0L;
        if (SUCCESS_CODE.equals(code)) {
            JSONObject dataObj = (JSONObject) bodyVal.getObj("data");
            JSONArray array = dataObj.getJSONArray("list");
            count = dataObj.getLong("count");
            if (CollUtil.isNotEmpty(array)) {
                for (int i = 0; i < array.size(); i++) {
                    GetUserDesignsRespVO respVO = new GetUserDesignsRespVO();
                    JSONObject item = (JSONObject) array.get(i);
                    String kindName = item.getStr("kindName");
                    Integer kindId = item.getInt("kindId");
                    String designId = item.getStr("designId");
                    String designTitle = item.getStr("designTitle");
                    String designWidth = item.getStr("designWidth");
                    String designHeight = item.getStr("designHeight");
                    Integer createTime = item.getInt("createTime");
                    Integer updateTime = item.getInt("updateTime");
                    String thumbUrl = item.getStr("thumbUrl");
                    Integer thumbnailsState = item.getInt("thumbnailsState");
                    Boolean mobileShow = item.getBool("mobileShow");
                    List<Integer> templateIds = item.getBeanList("templateId", Integer.class);
                    respVO.setKindName(kindName);
                    respVO.setKindId(kindId);
                    respVO.setDesignId(designId);
                    respVO.setDesignWidth(designWidth);
                    respVO.setDesignTitle(designTitle);
                    respVO.setDesignHeight(designHeight);
                    respVO.setCreateTime(createTime);
                    respVO.setUpdateTime(updateTime);
                    respVO.setThumbUrl(thumbUrl);
                    respVO.setThumbnailsState(thumbnailsState);
                    respVO.setMobileShow(mobileShow);
                    respVO.setTemplateIds(templateIds);
                    list.add(respVO);
                }
            }
        } else {
            log.error("getUserDesigns:{}", bodyVal.getStr("msg"));
        }

        PageResult<GetUserDesignsRespVO> result = new PageResult<>();
        result.setTotal(count);
        result.setList(list);
        return result;
    }

    @Override
    public Boolean deleteDesign(DeleteDesignReqVO reqVO) {
        boolean result = Boolean.FALSE;
        String url = openPlatformBaseUrl + "/deleteDesign.do";
        Map<String, Object> params = new HashMap<>(9);
        params.put("app_id", appId);
        params.put("user_flag", reqVO.getUserFlag());
        params.put("token", reqVO.getToken());
        params.put("design_ids", reqVO.getDesignIds());
        if (ObjectUtil.isNotNull(reqVO.getTerminal())) {
            params.put("terminal", reqVO.getTerminal());
        }
        String post = HttpUtil.post(url, params);
        JSONObject bodyObject = JSONUtil.parseObj(post);
        JSONObject bodyVal = (JSONObject) bodyObject.get("body");
        Integer code = bodyVal.getInt("code");
        if (SUCCESS_CODE.equals(code)) {
            result = Boolean.TRUE;
        } else {
            log.error("deleteDesign:{}", bodyVal.getStr("msg"));
        }
        return result;
    }

    @Override
    public CopyDesignRespVO copyDesign(CopyDesignReqVO reqVO) {
        CopyDesignRespVO respVO = new CopyDesignRespVO();
        String url = openPlatformBaseUrl + "/copyDesign.do";
        Map<String, Object> params = new HashMap<>(5);
        params.put("app_id", appId);
        params.put("user_flag", reqVO.getUserFlag());
        params.put("token", reqVO.getToken());
        params.put("design_id", reqVO.getDesignId());
        if (ObjectUtil.isNotNull(reqVO.getTerminal())) {
            params.put("terminal", reqVO.getTerminal());
        }
        String post = HttpUtil.post(url, params);
        JSONObject bodyObject = JSONUtil.parseObj(post);
        JSONObject bodyVal = (JSONObject) bodyObject.get("body");
        Integer code = bodyVal.getInt("code");
        if (SUCCESS_CODE.equals(code)) {
            String designId = bodyVal.getStr("data");
            respVO.setDesignId(designId);
        } else {
            log.error("copyDesign:{}", bodyVal.getStr("msg"));
        }
        return respVO;
    }

    @Override
    public Boolean updateTitle(UpdateTitleReqVO reqVO) {
        boolean result = Boolean.FALSE;
        String url = openPlatformBaseUrl + "/updateTitle.do";
        Map<String, Object> params = new HashMap<>(5);
        params.put("app_id", appId);
        params.put("user_flag", reqVO.getUserFlag());
        params.put("token", reqVO.getToken());
        params.put("design_id", reqVO.getDesignId());
        params.put("title", reqVO.getTitle());
        if (ObjectUtil.isNotNull(reqVO.getTerminal())) {
            params.put("terminal", reqVO.getTerminal());
        }
        String post = HttpUtil.post(url, params);
        JSONObject bodyObject = JSONUtil.parseObj(post);
        JSONObject bodyVal = (JSONObject) bodyObject.get("body");
        Integer code = bodyVal.getInt("code");
        if (SUCCESS_CODE.equals(code)) {
            result = Boolean.TRUE;
        } else {
            log.error("updateTitle:{}", bodyVal.getStr("msg"));
        }
        return result;
    }

    @Override
    public Boolean templateCollection(TemplateCollectionReqVO reqVO) {
        boolean result = Boolean.FALSE;
        String url = openPlatformBaseUrl + "/templateCollection/collection.do";
        Map<String, Object> params = new HashMap<>(4);
        params.put("app_id", appId);
        params.put("user_flag", reqVO.getUserFlag());
        params.put("token", reqVO.getToken());
        params.put("template_id", reqVO.getTemplateId());
        String post = HttpUtil.post(url, params);
        JSONObject bodyObject = JSONUtil.parseObj(post);
        JSONObject bodyVal = (JSONObject) bodyObject.get("body");
        Integer code = bodyVal.getInt("code");
        if (SUCCESS_CODE.equals(code)) {
            result = Boolean.TRUE;
        } else {
            log.error("templateCollection:{}", bodyVal.getStr("msg"));
        }
        return result;
    }

    @Override
    public Boolean templateCancelCollection(TemplateCancelCollectionReqVO reqVO) {
        boolean result = Boolean.FALSE;
        String url = templateCollectionBaseUrl + "/cancelCollection.do";
        Map<String, Object> params = new HashMap<>(4);
        params.put("app_id", appId);
        params.put("user_flag", reqVO.getUserFlag());
        params.put("token", reqVO.getToken());
        params.put("template_id", reqVO.getTemplateId());
        String post = HttpUtil.post(url, params);
        JSONObject bodyObject = JSONUtil.parseObj(post);
        JSONObject bodyVal = (JSONObject) bodyObject.get("body");
        Integer code = bodyVal.getInt("code");
        if (SUCCESS_CODE.equals(code)) {
            result = Boolean.TRUE;
        } else {
            log.error("templateCancelCollection:{}", bodyVal.getStr("msg"));
        }
        return result;
    }

    @Override
    public List<TemplateCollectionListRespVO> getTemplateCollection(TemplateCollectionListReqVO reqVO) {
        String url = templateCollectionBaseUrl + "/getCollection.do";
        Map<String, Object> params = new HashMap<>(9);
        params.put("app_id", appId);
        params.put("user_flag", reqVO.getUserFlag());
        params.put("token", reqVO.getToken());
        params.put("page_no", reqVO.getPageNo());
        params.put("page_size", reqVO.getPageSize());
        if (ObjectUtil.isNotNull(reqVO.getKindId())) {
            params.put("kind_id", reqVO.getKindId());
        }

        String post = HttpUtil.post(url, params);
        JSONObject bodyObject = JSONUtil.parseObj(post);
        JSONObject bodyVal = (JSONObject) bodyObject.get("body");
        Integer code = bodyVal.getInt("code");
        List<TemplateCollectionListRespVO> list = new ArrayList<>();
        if (SUCCESS_CODE.equals(code)) {
            JSONObject dataObj = (JSONObject) bodyVal.getObj("data");
            JSONArray array = dataObj.getJSONArray("list");
            if (CollUtil.isNotEmpty(array)) {
                for (int i = 0; i < array.size(); i++) {
                    TemplateCollectionListRespVO respVO = new TemplateCollectionListRespVO();
                    JSONObject item = (JSONObject) array.get(i);
                    Integer templateId = item.getInt("templateId");
                    String templateTitle = item.getStr("templateTitle");
                    Integer kindId = item.getInt("kindId");
                    String kindName = item.getStr("kindName");
                    String createTime = item.getStr("createTime");
                    String imageUrl = item.getStr("imageUrl");
                    String width = item.getStr("width");
                    String height = item.getStr("height");
                    Integer price = item.getInt("price");
                    respVO.setTemplateId(templateId);
                    respVO.setTemplateTitle(templateTitle);
                    respVO.setKindName(kindName);
                    respVO.setKindId(kindId);
                    respVO.setCreateTime(createTime);
                    respVO.setImageUrl(imageUrl);
                    respVO.setWidth(width);
                    respVO.setHeight(height);
                    respVO.setPrice(price);
                    list.add(respVO);
                }
            }
        } else {
            log.error("getTemplateCollection:{}", bodyVal.getStr("msg"));
        }
        return list;
    }

    @Override
    public TemplateForApiUserRespVO queryTemplateForApiUser(TemplateForApiUserReqVO reqVO) {
        String url = templateBaseUrl + "/queryTemplateForApiUser.do";
        Map<String, Object> params = new HashMap<>(9);
        params.put("appId", appId);
        params.put("apiToken", reqVO.getApiToken());
        params.put("kindIds", reqVO.getKindIds());
        String post = HttpUtil.post(url, params);
        JSONObject bodyObject = JSONUtil.parseObj(post);
        JSONObject bodyVal = (JSONObject) bodyObject.get("body");
        Integer code = bodyVal.getInt("code");
        TemplateForApiUserRespVO respVO = null;
        List<TemplateForApiUserRespVO.QueryDesignTemplateBeanListDTO> list = new ArrayList<>();
        if (SUCCESS_CODE.equals(code)) {
            respVO = new TemplateForApiUserRespVO();
            JSONObject dataObj = (JSONObject) bodyVal.getObj("data");
            Boolean hasNext = dataObj.getBool("hasNext");
            Integer totalCount = dataObj.getInt("totalCount");
            Integer resultCount = dataObj.getInt("resultCount");
            JSONArray array = dataObj.getJSONArray("queryDesignTemplateBeanList");
            if (CollUtil.isNotEmpty(array)) {
                for (int i = 0; i < array.size(); i++) {
                    TemplateForApiUserRespVO.QueryDesignTemplateBeanListDTO dataItem = new TemplateForApiUserRespVO.QueryDesignTemplateBeanListDTO();
                    JSONObject item = (JSONObject) array.get(i);
                    String designTemplateImageUrl = item.getStr("designTemplateImageUrl");
                    Integer designKindId = item.getInt("designKindId");
                    Integer designTemplateId = item.getInt("designTemplateId");
                    String templateTitle = item.getStr("templateTitle");
                    String customThumbnailsUrl = item.getStr("customThumbnailsUrl");
                    String cutDownTemplateImageUrl = item.getStr("cutDownTemplateImageUrl");
                    Integer price = item.getInt("price");
                    Integer priceType = item.getInt("priceType");
                    String keywords = item.getStr("keywords");
                    String width = item.getStr("width");
                    String height = item.getStr("height");
                    dataItem.setDesignTemplateImageUrl(designTemplateImageUrl);
                    dataItem.setDesignKindId(designKindId);
                    dataItem.setDesignTemplateId(designTemplateId);
                    dataItem.setTemplateTitle(templateTitle);
                    dataItem.setCustomThumbnailsUrl(customThumbnailsUrl);
                    dataItem.setCutDownTemplateImageUrl(cutDownTemplateImageUrl);
                    dataItem.setWidth(width);
                    dataItem.setHeight(height);
                    dataItem.setPrice(price);
                    dataItem.setPriceType(priceType);
                    dataItem.setKeywords(keywords);
                    list.add(dataItem);
                }
                respVO.setHasNext(hasNext);
                respVO.setResultCount(resultCount);
                respVO.setTotalCount(totalCount);
                respVO.setQueryDesignTemplateBeanList(list);
            }
        } else {
            log.error("queryTemplateForApiUser:{}", bodyVal.getStr("msg"));
        }
        return respVO;
    }

    @Override
    public String getTemplateCenterSign(Map<String, String> params) {
        Map<String, String> paramsMap = new TreeMap<>();
        paramsMap.put("app_id", params.get("appId"));
        paramsMap.put("app_secret", appSecret);
        paramsMap.put("setting_code", params.get("settingCode"));
        paramsMap.put("timestamp", params.get("timestamp"));

        String waitForSign = paramsMap.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).collect(Collectors.joining("&"));
        return DigestUtil.md5Hex(waitForSign).toUpperCase();
    }

    @Override
    public String getTemplateEditorSign(TreeMap<String, String> params) {
        String waitForSign = params.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).collect(Collectors.joining("&")) + appSecret;
        log.info("waiting to sign: {}", waitForSign);
        return DigestUtil.md5Hex(waitForSign).toUpperCase();
    }

    @Override
    public String requestPackageId() {
        return packageId;
    }

    public static void main(String[] args) {
        String url = "https://gw.chuangkit.com/openplatform/openApi/getApiToken.do";
        Map<String, Object> params = new HashMap<>();
        params.put("api_id", "1cf71fc825044b6ea6858ce9bbd8b663");
        Long timestamp = System.currentTimeMillis();
        params.put("timestamp", timestamp);
        String val = "appId&1cf71fc825044b6ea6858ce9bbd8b663"
                + "timestamp&" + timestamp + "#12AC40EE69C9866487DAD7085E75DCAE";
        String sign = DigestUtil.md5Hex(val).toUpperCase();
        params.put("sign", sign);
        String post = HttpUtil.post(url, params);
        JSONObject bodyObject = JSONUtil.parseObj(post);
        JSONObject bodyVal = (JSONObject) bodyObject.get("body");
        Integer code = bodyVal.getInt("code");
        if (SUCCESS_CODE.equals(code)) {
            JSONObject dataObj = (JSONObject) bodyVal.getObj("data");
            String accessToken = dataObj.getStr("accessToken");
            Long tokenExpireTime = dataObj.getLong("tokenExpireTime");
            String refreshToken = dataObj.getStr("refreshToken");
            Long refreshTokenExpireTime = dataObj.getLong("refreshTokenExpireTime");
        }
        System.out.println(bodyObject);

    }
}
